package com.example.mh_flutter_amap_search

import android.content.Context
import androidx.annotation.NonNull
import com.amap.api.services.core.LatLonPoint
import com.amap.api.services.core.PoiItem
import com.amap.api.services.geocoder.*
import com.amap.api.services.help.Inputtips
import com.amap.api.services.help.InputtipsQuery
import com.amap.api.services.help.Tip
import com.amap.api.services.poisearch.PoiResult
import com.amap.api.services.poisearch.PoiSearch
import com.amap.api.services.route.DistanceSearch
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import java.util.function.DoubleBinaryOperator


/** MhFlutterAmapSearchPlugin */
class MhFlutterAmapSearchPlugin : FlutterPlugin, MethodCallHandler{
    /// The MethodChannel that will the communication between Flutter and native Android
    ///
    /// This local reference serves to register the plugin with the Flutter Engine and unregister it
    /// when the Flutter Engine is detached from the Activity
    private lateinit var channel: MethodChannel
    private lateinit var context: Context
//    private lateinit var handler:AmapCallbackHandler

    override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
        channel = MethodChannel(flutterPluginBinding.binaryMessenger, "mh_flutter_amap_search")
        channel.setMethodCallHandler(this)
        context = flutterPluginBinding.applicationContext
//        handler = AmapCallbackHandler()
    }

    override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {

        when (call.method) {
            "getPlatformVersion" -> {
                result.success("Android ${android.os.Build.VERSION.RELEASE}")
            }
            "setApiKey" -> {

            }
            "searchKeyword" -> {
                val  argument = call.arguments as Map<*, *>
              var keyword = argument["keyword"].toString()
              var city = argument["city"].toString()
              var query = PoiSearch.Query( keyword, "", city)
              query.pageNum = argument["page"] as Int
              query.pageSize = argument["pageSize"] as Int
              val poiSearch = PoiSearch(
                context, query
              )
              poiSearch.setOnPoiSearchListener(AmapCallbackHandler("keySearch",channel))
              poiSearch.searchPOIAsyn()
            }
            "searchAround" -> {
                val  argument = call.arguments as Map<*, *>
                var keyword = argument["keyword"].toString()
                var city = argument["city"].toString()
                var query = PoiSearch.Query( keyword, "", city)
                val  latitude = argument["latitude"] as Double
                val  longitude = argument["longitude"] as Double
                val  radius = argument["radius"] as Int
                query.pageNum = argument["page"] as Int
                query.pageSize = argument["pageSize"] as Int
                val poiSearch = PoiSearch(
                    context, query
                )
                poiSearch.bound = PoiSearch.SearchBound(
                    LatLonPoint(
                        latitude,
                        longitude
                    ), radius
                ) //设置周边搜索的中心点以及半径

                poiSearch.setOnPoiSearchListener(AmapCallbackHandler("aroundSearch",channel))
                poiSearch.searchPOIAsyn()
            }
            "searchPoiId" -> {
                val  argument = call.arguments as Map<*, *>
                var uid = argument["uid"].toString()
                val poiSearch = PoiSearch(
                    context, null
                )
                poiSearch.setOnPoiSearchListener(AmapCallbackHandler("idSearch",channel))
                poiSearch.searchPOIIdAsyn(uid)
            }
            "searchGeocode" -> {
                val  argument = call.arguments as Map<*, *>
                var keyword = argument["address"].toString()
                var city = argument["city"] as String
               val geocoderSearch = GeocodeSearch(context)
                geocoderSearch.setOnGeocodeSearchListener(AmapCallbackHandler("geoSearch",channel))
                // name表示地址，第二个参数表示查询城市，中文或者中文全拼，citycode、adcode
                val query = GeocodeQuery(keyword, city)
                geocoderSearch.getFromLocationNameAsyn(query)
            }
            "searchReGeocode" -> {
                val  argument = call.arguments as Map<*, *>
                val  latitude = argument["latitude"] as Double
                val  longitude = argument["longitude"] as Double
                val  radius = argument["radius"] as Double
                val geocoderSearch = GeocodeSearch(context)
                geocoderSearch.setOnGeocodeSearchListener(AmapCallbackHandler("reGeoSearch",channel))
                // 第一个参数表示一个Latlng，第二参数表示范围多少米，第三个参数表示是火系坐标系还是GPS原生坐标系
                val query = RegeocodeQuery(
                    LatLonPoint(latitude,longitude),
                    radius.toFloat(), GeocodeSearch.AMAP)

                geocoderSearch.getFromLocationAsyn(query)
            }
            "fetchInputTips" -> {
                val  argument = call.arguments as Map<*, *>
                val newText = argument["keyword"] as String
                val city = argument["city"] as String
                val inputquery = InputtipsQuery(newText, city)
                inputquery.cityLimit = true //限制在当前城市
                val inputTips = Inputtips(context, inputquery)
                inputTips.setInputtipsListener(AmapCallbackHandler("inputTipsSearch",channel))
                inputTips.requestInputtipsAsyn()
            }
            "distanceSearch" -> {
                val  argument = call.arguments as Map<*, *>
                val  originMaps = argument["origins"] as MutableList<Map<*,*>>
                val  origins = originMaps.map { LatLonPoint(it["latitude"] as Double, it["longitude"] as Double) }
                val  type = argument["type"] as Int
                val  destination = argument["destination"] as Map<*,*>
                val distanceReq = DistanceSearch.DistanceQuery()

                distanceReq.destination = LatLonPoint(destination["latitude"] as Double,destination["longitude"] as Double)
                distanceReq.origins = origins
                distanceReq.type = type
                val distanceSearch = DistanceSearch(context)
                distanceSearch.setDistanceSearchListener(AmapCallbackHandler("distanceSearch",channel))
                distanceSearch.calculateRouteDistanceAsyn(distanceReq)


            }
        }
}

    override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
        channel.setMethodCallHandler(null)
    }

}
